<script lang="ts">
export default {
  name: "ChannelEditDialog"
}
</script>

<!--
 * @Description: 编辑对话框
 * @version:
 * @Author:
 * @Date: 2022-10-24 09:10:28
 * @LastEditors:
 * @LastEditTime: 2022-10-24 09:10:28
-->
<template>
  <!-- 对话框 -->
  <el-dialog :close-on-click-modal="false" :model-value="visible" :title="title" min-width="1000px"
             @close="handleCancel">

    <!-- 数据表单 -->
    <el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="80px">

      <!-- 编辑框：通道名称 -->
      <el-form-item label="通道名称" prop="channelName">
        <el-input v-model="formData.channelName" :disabled="type==='update'"/>
      </el-form-item>

      <!-- 下拉框：通道类型 -->
      <el-form-item label="通道类型" prop="channelType">
        <el-select v-model="formData.channelType" :disabled="type==='update'" allow-create filterable placeholder="请选择"
                   @change="handleSelectChannelType">
          <el-option
            v-for="item in channelTypeOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>


      <el-form-item label="设备厂商" prop="manufacturer">
        <el-select v-model="dataState.formData.manufacturer"  placeholder="请选择"
                   @change="handleSelectManufacturer">
          <el-option
            v-for="item in dataState.manufacturerOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>

        <el-form-item label="设备类型" prop="deviceType">
          <el-select v-model="formData.deviceType" placeholder="请选择"
                     @change="handleSelectDeviceType">
            <el-option
              v-for="item in dataState.deviceTypeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
      </el-form-item>

      <el-form-item label="子集名称" prop="subsetName">
        <el-select v-model="dataState.formData.subsetName"  placeholder="请选择"
                   @change="handleSelectSubsetName">
          <el-option
            v-for="item in dataState.subsetNameOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>

        <el-form-item label="模板名称" prop="templateName">
          <el-select v-model="dataState.formData.templateName" placeholder="请选择">
            <el-option
              v-for="item in dataState.templateNameOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>


        <el-form-item label="填入参数" prop="templateName">
          <el-button :icon="Download"  circle plain type="success"  :disabled="dataState.formData.templateName === '' || dataState.formData.channelType === ''"
                     @click="handleChannelParam"></el-button>
        </el-form-item>
      </el-form-item>

      <!-- 下拉框：通道参数 -->
      <el-form-item label="配置参数" prop="channelParamJson">
        <el-input v-model="formData.channelParamJson" :autosize="{ minRows: 1, maxRows: 100 }" type="textarea"/>
      </el-form-item>

      <el-form-item label="扩展参数" prop="channelParamJson">
        <el-input v-model="formData.extendParamJson" :autosize="{ minRows: 1, maxRows: 100 }" type="textarea"/>
      </el-form-item>

    </el-form>

    <!-- 脚部：确认/取消按钮-->
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="handleSubmit">确 定</el-button>
        <el-button @click="handleCancel">取 消</el-button>
      </div>
    </template>

  </el-dialog>
</template>

<script lang="ts" setup>
import {nextTick, onMounted, reactive, ref, toRefs} from "vue";

import {Download} from '@element-plus/icons-vue';
import {ElForm, ElMessage} from "element-plus";
import {ChannelItem} from "@/api/channel/types";
import {listChannelTypeList} from "@/api/channel";
import {listOption4List, listOptionList} from "@/api/option";
import {listDeviceTemplateEntities, listDeviceTemplateOptions} from "@/api/repo/comp/local";
import {isEmpty} from "@/utils/fieldutil";

const props = defineProps(['visible']);
const emit = defineEmits(['create', 'update', 'cancel']); //注意：这个是父组件<dict-type-edit>标签上的@close
const dataFormRef = ref(ElForm); // 属性名必须和元素的ref属性值一致

/**
 * 对外声明接口：父页面可以调用它
 */
defineExpose({initEditData});

// 数据状态：定义
let dataState = reactive({
  // 类型：create/update
  type: 'create',
  // 标题
  title: '添加设备',
  // 表单数据
  formData: {
    id: undefined,
    manufacturer: '',
    deviceType: '',
    subsetName: '',
    templateName: '',

    channelType: '',
    channelName: '',
    channelParam: {},
    channelParamJson: '',
    extendParam: {},
    extendParamJson: '',
  } as any,

  // 厂商类型选项
  manufacturerOptions: [] as OptionType[],
  // 设备类型选项
  deviceTypeOptions: [] as OptionType[],
  // 设备模板的子集
  subsetNameOptions: [] as OptionType[],
  // 设备模板的子集
  templateNameOptions: [] as OptionType[],

  // 通道类型选项
  channelTypeOptions: [] as OptionType[],
  // 通道名称选项
  channelNameOptions: [] as OptionType[],

  // 对话框的各控件输入规则
  rules: {
    channelName: [{required: true, message: '通道名称不能为空', trigger: 'blur'}],
    channelType: [{required: true, message: '通道类型不能为空', trigger: 'blur'}],
    channelParamJson: [{required: true, message: '配置参数不能为空', trigger: 'blur'}],
    extendParamJson: [{required: true, message: '扩展参数不能为空', trigger: 'blur'}],
  },
});

// 数据状态：双向引用
const {
  // 类型：create/update
  type,
  // 标题
  title,
  //表单数据
  formData,
  // 通道类型选项
  channelTypeOptions,
  // 通道名称选项
  channelNameOptions,
  // 对话框输入约束规则
  rules,
} = toRefs(dataState);

async function handleSelectChannelType(value: any) {
  dataState.formData.channelType = value;

  dataState.formData.manufacturer = '';
  dataState.formData.deviceType = '';
  dataState.formData.subsetName = '';
  dataState.formData.templateName = '';

  await listManufacturerOptions(true);
  await listDeviceTypeOptions(true);
  await listSubsetNameOptions(true);
  await listTemplateNameOptions(true);
}

async function handleSelectManufacturer(value: any) {
  dataState.formData.manufacturer = value;

  dataState.formData.deviceType = '';
  dataState.formData.subsetName = '';
  dataState.formData.templateName = '';

  await listDeviceTypeOptions(true);
  await listSubsetNameOptions(true);
  await listTemplateNameOptions(true);
}

async function handleSelectDeviceType(value: any) {
  dataState.formData.deviceType = value;

  dataState.formData.subsetName = '';
  dataState.formData.templateName = '';

  await listSubsetNameOptions(true);
  await listTemplateNameOptions(true);
}

async function handleSelectSubsetName(value: any) {
  dataState.formData.subsetName = value;

  dataState.formData.templateName = '';

  await listTemplateNameOptions(true);
}

async function listManufacturerOptions(value: any) {
  dataState.formData.manufacturer = '';

  let params = [];
  params.push({field:'templateType',value:'channel-param'});
  params.push({field:'templateName',value:dataState.formData.channelType});
  await listOption4List("DeviceTemplateEntity", "manufacturer", params).then(({data}) => {
    dataState.manufacturerOptions = data;
    if (dataState.manufacturerOptions.length > 0){
      dataState.formData.manufacturer = dataState.manufacturerOptions[0].value;
    }
  });
}


async function listDeviceTypeOptions(value: any) {
  dataState.formData.deviceType = '';

  let params = [];
  params.push({field:'templateType',value:'channel-param'});
  params.push({field:'templateName',value:dataState.formData.channelType});
  params.push({field:'manufacturer',value:dataState.formData.manufacturer});
  await listOption4List("DeviceTemplateEntity", "deviceType", params).then(({data}) => {
    dataState.deviceTypeOptions = data;
    if (dataState.deviceTypeOptions.length > 0){
      dataState.formData.deviceType = dataState.deviceTypeOptions[0].value;
    }
  });
}

async function listSubsetNameOptions(value: any) {
  let params = [];
  params.push({field:'templateType',value:'channel-param'});
  params.push({field:'templateName',value:dataState.formData.channelType});
  params.push({field:'manufacturer',value:dataState.formData.manufacturer});
  params.push({field:'deviceType',value:dataState.formData.deviceType});
  await listOption4List("DeviceTemplateEntity", "subsetName", params).then(({data}) => {
    dataState.subsetNameOptions = data;
    if (dataState.subsetNameOptions.length > 0){
      dataState.formData.subsetName = dataState.subsetNameOptions[0].value;
    }
  });
}

async function listTemplateNameOptions(value: any) {
  if (isEmpty(dataState.formData.manufacturer) || isEmpty(dataState.formData.deviceType) || isEmpty(dataState.formData.subsetName)|| isEmpty(dataState.formData.channelType)){
    return;
  }

  let queryParams = {
    manufacturer: dataState.formData.manufacturer,
    deviceType: dataState.formData.deviceType,
    subsetName: dataState.formData.subsetName,
    templateType: 'channel-param',
    channelType: dataState.formData.channelType,
    field: 'templateName',
  };

  await listDeviceTemplateOptions(queryParams).then(({data}) => {
    dataState.templateNameOptions = data;
    dataState.formData.templateName = '';
    if (dataState.templateNameOptions.length > 0){
      dataState.formData.templateName = dataState.templateNameOptions[0].value;
    }
  });
}

async function handleChannelParam(value: any) {
  debugger
  let queryParams = {
    manufacturer: dataState.formData.manufacturer,
    deviceType: dataState.formData.deviceType,
    subsetName: dataState.formData.subsetName,
    templateName: dataState.formData.templateName,
    templateType: 'channel-param',
  };
  listDeviceTemplateEntities(queryParams).then(({data}) => {
    if (data.length == 0){
      return;
    }
    dataState.formData.channelParamJson = JSON.stringify( data[0].templateParam.param, null, 5);
  });
}

function handleCancel() {
  //执行调用<channel-edit-dialog @cancel="cancelEdit">
  emit('cancel', "子组件传给父组件的值");
}

/**
 * 确认：新增/修改实体
 */
function handleSubmit() {
  if (dataState.formData.channelName === '') {
    ElMessage.info('名称不能为空');
    return;
  }

  try {
    formData.value.channelParam = JSON.parse(formData.value.channelParamJson);
  } catch (e) {
    ElMessage.info('配置参数的格式，不是合法的JSON格式!');
    return;
  }

  try {
    formData.value.extendParam = JSON.parse(formData.value.extendParamJson);
  } catch (e) {
    ElMessage.info('扩展参数的格式，不是合法的JSON格式!');
    return;
  }

  if (type.value === 'create') {
    // 执行调用<channel-edit-dialog @create="createEdit">的create
    emit('create', formData.value);
  }
  if (type.value === 'update') {
    //执行调用<channel-edit-dialog @update="updateEdit">
    emit('update', formData.value);
  }
}

/**
 * 初始化对话框
 * @taskParam type 对话框类型
 * @taskParam entity 实体
 */
async function initEditData(type: string, entity: ChannelItem) {
  if (type === 'create') {
    dataState.type = type;
    dataState.title = '新增通道';

    dataState.formData.id = undefined;
    dataState.formData.channelName = '';
    dataState.formData.channelType = '';
    dataState.formData.channelParam = {};
    dataState.formData.extendParam = {};
    dataState.formData.channelParamJson = '{}';
    dataState.formData.extendParamJson = '{}';

    nextTick(() => {
      dataFormRef.value.resetFields();
    })

    return;
  }

  if (type === 'update') {
    dataState.type = type;
    dataState.title = '修改通道';

    dataState.formData.id = entity.id;
    dataState.formData.channelName = entity.channelName;
    dataState.formData.channelType = entity.channelType;
    dataState.formData.channelParam = entity.channelParam;
    dataState.formData.channelParamJson = JSON.stringify(entity.channelParam, null, 5);
    dataState.formData.extendParam = entity.extendParam;
    dataState.formData.extendParamJson = JSON.stringify(entity.extendParam, null, 5);


    // 填充下拉列表
    await listManufacturerOptions(true);
    await listDeviceTypeOptions(true);
    await listSubsetNameOptions(true);
    await listTemplateNameOptions(true);
    return;
  }
}

/**
 * 响应页面安装：页面的初始化工作
 */
onMounted(() => {
  // 查询通道类型选项，并保存在存量区
  listChannelTypeList().then(({data}) => {
    for (let type of data) {
      channelTypeOptions.value.push({value: type, label: type} as OptionType);
    }
  });
});

</script>
